package top.wangjiu.java.jvm.accessflag;

import lombok.Getter;

import java.util.ArrayList;
import java.util.List;

/**
 * ACC_PUBLIC	0x0001	public，方法可以从包外访问
 * ACC_PRIVATE	0x0002	private，方法只能本类中访问
 * ACC_PROTECTED	0x0004	protected，方法在自身和子类可以访问
 * ACC_STATIC	0x0008	static，静态方法
 * ACC_FINAL	0x0010	final，方法不能被重写（覆盖）
 * ACC_SYNCHRONIZED	0x0020	synchronized，方法由管程同步
 * ACC_BRIDGE	0x0040	bridge，方法由编译器产生
 * ACC_VARARGS	0x0080	表示方法带有变长参数
 * ACC_NATIVE	0x0100	native，方法引用非 java 语言的本地方法
 * ACC_ABSTRACT	0x0400	abstract，方法没有具体实现
 * ACC_STRICT	0x0800	strictfp，方法使用 FP-strict 浮点格式
 * ACC_SYNTHETIC	0x1000	方法在源文件中不出现，由编译器产生
 *
 */
public enum MethodAccessFlag {

    ACC_PUBLIC(1),
    ACC_PRIVATE(2),
    ACC_PROTECTED(4),
    ACC_STATIC(8),
    ACC_FINAL(1<<4),
    ACC_SYNCHRONIZED(2<<4),
    ACC_BRIDGE(4<<4),
    ACC_VARARGS(8<<4),
    ACC_NATIVE(1<<8),
    ACC_ABSTRACT(4<<8),
    ACC_STRICT(8<<8),
    ACC_SYNTHETIC(1<<12);

    @Getter
    private final short flag;

    MethodAccessFlag(int flag){
        this.flag = (short) flag;
    }

    public static MethodAccessFlag[] parseAccessFlags(short accessFlags){
        List<MethodAccessFlag> list = new ArrayList<>();
        for (MethodAccessFlag value : MethodAccessFlag.values()) {
            if((value.flag & accessFlags) == value.flag){
                list.add(value);
            }
        }
        return list.toArray(new MethodAccessFlag[list.size()]);
    }
    
    @Override
    public String toString() {
        return this.name();
    }
}
